package com.ld.tamp.web.controller;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.ld.tamp.web.constant.WebConstant;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.DocumentException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import com.alibaba.fastjson.JSON;
import com.ld.base.helper.DateUtils;
import com.ld.base.support.PropertyHolder;
import com.ld.base.web.controller.BaseController;
import com.ld.tamp.web.request.ArticlePageParam;
import com.ld.tamp.web.request.TemplateMsgItemParam;
import com.ld.tamp.web.service.AuthorizationService;
import com.ld.tamp.web.service.WeChatService;
import com.qq.weixin.mp.aes.AesException;

import weixin.popular.bean.BaseResult;
import weixin.popular.bean.material.MaterialBatchgetResult;
import weixin.popular.bean.material.MaterialcountResult;
import weixin.popular.bean.menu.Menu;
import weixin.popular.bean.message.templatemessage.TemplateMessageItem;

/**
 * @author KeYang
 *
 */
@Controller
@RequestMapping("/wechat")
public class WeChatController extends BaseController{

	private Logger logger = LoggerFactory.getLogger(WeChatController.class);

	protected static String ADMIN_URL = "admin.domain";

	@Autowired
	private AuthorizationService authorizationService;

	@Autowired
	private WeChatService weChatService;
	
	private static Map<Long,String> cacheDomian = new LinkedHashMap <Long,String>();

	/**
	 * 数据流输出
	 * 
	 * @param outputStream
	 * @param text
	 * @return
	 */

	private boolean outputStreamWrite(OutputStream outputStream, String text) {
		try {
			outputStream.write(text.getBytes("utf-8"));
			outputStream.flush();
			outputStream.close();
		} catch (UnsupportedEncodingException e) {
			logger.error("不支持的字符格式", e);
			return false;
		} catch (IOException e) {
			logger.error("发送数据失败", e);
			return false;
		}
		return true;
	}

	/**
	 * =============================以下代码是给第三方开放平台用的====================================================================
	 */

	/**
	 * 用于接收取消授权通知、授权成功通知、授权更新通知，也用于接收component_verify_ticket
	 * 
	 * @param request
	 * @param response
	 * @throws Exception
	 */
	@RequestMapping(value = "/authorize")
	@ResponseStatus(HttpStatus.NO_CONTENT)
	public void acceptAuthorizeEvent(HttpServletRequest request, HttpServletResponse response) throws Exception {
		logger.info("微信第三方平台---------微信推送Ticket消息10分钟一次-----------" + DateUtils.date2String(new Date(), "yyyyMMdd HH:mm:ss"));
		authorizationService.processAuthorizeEvent(request, response);// 处理事件
		ServletOutputStream outputStream = response.getOutputStream();
		outputStreamWrite(outputStream, "success");
	}

	/**
	 * 公众号授权页面
	 * 
	 * @param request
	 * @param response
	 * @throws IOException
	 * @throws AesException
	 * @throws DocumentException
	 */
	@RequestMapping(value = "/getAuthUrl", method = RequestMethod.GET)
	public String goAuthor(@RequestParam("co_no") Long companyNo, HttpServletRequest request, HttpServletResponse response) throws Exception {

		StringBuffer requestUrl = request.getRequestURL();
		String redirectUrl = requestUrl.delete(requestUrl.length() - request.getRequestURI().length(), requestUrl.length()).append("/wechat/authCallback?co_no=").append(companyNo)
				.toString();
		String authUrl = authorizationService.generateAuthUrl(redirectUrl);
		HttpSession session = getSession();
		session.setAttribute("authUrl", authUrl);
		
		return "auth";
	}

	/**
	 * 授权回调
	 * 
	 * @param request
	 * @param response
	 * @throws IOException
	 * @throws AesException
	 */
	@RequestMapping(value = "/authCallback", method = RequestMethod.GET)
	public void authorCallback(@RequestParam("co_no") Long companyNo, @RequestParam("auth_code") String authCode, HttpServletRequest request, HttpServletResponse response)
			throws IOException, AesException {
		authorizationService.saveAuthInfo(companyNo, authCode);
		String url = PropertyHolder.getProperty(ADMIN_URL)+"/#wechat/wx_config.html";
		response.sendRedirect(url);
	}

	/**
	 * 公众号消息与事件接收URL
	 * 
	 * @param request
	 * @param response
	 * @throws IOException
	 * @throws AesException
	 * @throws DocumentException
	 */
	@RequestMapping(value = "{appid}/callback")
	@ResponseStatus(HttpStatus.NO_CONTENT)
	public void acceptMessageAndEvent(@PathVariable String appid, HttpServletRequest request, HttpServletResponse response) throws IOException, AesException {

		logger.info("微信第三方平台--接收到公众号消息与事件---------" + DateUtils.date2String(new Date(), "yyyyMMdd HH:mm:ss"));
		weChatService.processMessageAndEvent(request, response);

	}
	
	
	/**
	 * 服务号登录页页面地址
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	@RequestMapping(value = "/getLoginUrl", method = RequestMethod.GET)
	public void goLogin(@RequestParam Long co_no, @RequestParam String user_type, HttpServletRequest request, HttpServletResponse response) throws IOException {
		StringBuffer requestUrl = request.getRequestURL();
		String domain = URLDecoder.decode(request.getParameter("domain"),"utf-8");
		String appid = domain.substring(domain.indexOf("//")+2,domain.indexOf("."));
		requestUrl.delete(requestUrl.length() - request.getRequestURI().length(), requestUrl.length())
			.append("/wechat/bind/callback?co_no=" + co_no+"&user_type="+user_type);
		cacheDomian.put(co_no,domain);
		logger.info("domain:{}",domain);
		String url = weChatService.generateWeChatBindUrl(co_no, appid, requestUrl.toString());
		//跳转到微信服务器，生成微信绑定页面
		response.sendRedirect(url);
	}
	
	
	/**
	 * 代公众号发起网页授权页面
	 * 
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	@RequestMapping(value = "/getBindUrl", method = RequestMethod.GET)
	public void goBind(@RequestParam Long co_no, @RequestParam(required = false) Long cust_no, @RequestParam(required = false) Long opor_no,
			@RequestParam String user_type, HttpServletRequest request, HttpServletResponse response) throws IOException { StringBuffer requestUrl = request.getRequestURL();
		String domain = URLDecoder.decode(request.getParameter("domain"),"utf-8");
		String appid = domain.substring(domain.indexOf("//")+2,domain.indexOf("."));
		requestUrl.delete(requestUrl.length() - request.getRequestURI().length(), requestUrl.length())
			.append("/wechat/bind/callback?co_no=" + co_no+"&user_type="+user_type);
		if(cust_no!=null){
			requestUrl.append("&cust_no=" + cust_no);
		}
		if(opor_no!=null){
			requestUrl.append("&opor_no=" + opor_no);
		}
		cacheDomian.put(co_no,domain);
		logger.info("domain:{}",domain);
		String url = weChatService.generateWeChatBindUrl(co_no, appid, requestUrl.toString());
		response.sendRedirect(url);
	}


	/**
	 *
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	@RequestMapping(value = "/bind/callback", method = RequestMethod.GET)
	public void bindCallback(HttpServletRequest request, HttpServletResponse response) throws IOException {
		String code = request.getParameter("code");
		Long co_no = Long.parseLong(request.getParameter("co_no"));
		String cust_no = request.getParameter("cust_no");
		String opor_no = request.getParameter("opor_no");
		String user_type = request.getParameter("user_type");
		String returnUrl;
		String url;
		String domain = cacheDomian.get(co_no);
		String appid = "";
		logger.info("domain:{}",domain);
		if(domain!=null){
			appid = domain.substring(domain.indexOf("//")+2,domain.indexOf("."));
		}
		logger.info("appid:{},user_type:{},cust_no:{},opor_no:{},code:{}",appid,user_type,cust_no,opor_no,code);
		if(StringUtils.isEmpty(code)){
			//没有授权码
			returnUrl = domain+"/loginback.do?appid={APPID}&ticket={TICKET}";
			url = weChatService.generateWxJsConfig(co_no,appid,returnUrl);
		}else{
			//有授权码
			returnUrl = domain+"/loginback.do?appid={APPID}&openid={OPENID}&ticket={TICKET}";
			if(WebConstant.USER_TYPE_CUSTOMER.equalsIgnoreCase(user_type)){
				if(StringUtils.isNotEmpty(cust_no)){
					url = weChatService.bindCuster(co_no,Long.valueOf(cust_no),appid,code,returnUrl);
				}else {
					url = weChatService.loginCuster(co_no,appid,code,returnUrl);
				}
			}else{
				if(StringUtils.isNotEmpty(opor_no)){
					url = weChatService.bindOpor(co_no,Long.valueOf(opor_no),appid,code,returnUrl);
				}else{
					url = weChatService.loginOpor(co_no,appid,code,returnUrl);
				}
			}
		}
		response.sendRedirect(url);
	}

	@RequestMapping(value = "/getMenu", method = RequestMethod.GET)
	@ResponseBody
	public Menu getMenu(@RequestParam("co_no")Long co_no,@RequestParam("app_id")String app_id ){
		return weChatService.getMenuList(co_no, app_id);
	}
	
	
	@RequestMapping(value = "/createMenu", method = RequestMethod.POST)
	@ResponseBody
	public BaseResult createMenu(@RequestParam("co_no")Long co_no,@RequestParam("app_id")String app_id){
		String menuJson = request.getParameter("menu");
		return weChatService.createMenu(co_no,app_id,menuJson);
	}
	
	
	@RequestMapping(value = "/getMaterialCount", method = RequestMethod.GET)
	@ResponseBody
	public MaterialcountResult getMaterialCount(@RequestParam("co_no")Long co_no,@RequestParam("app_id")String app_id){
		return weChatService.getMaterialCount(co_no,app_id);
	}
	
	@RequestMapping(value = "/getMaterialList", method = RequestMethod.POST)
	@ResponseBody
	public MaterialBatchgetResult getMaterialList(@RequestBody ArticlePageParam pageParam) throws IOException{
		Long co_no = pageParam.getCo_no();
		int start = pageParam.getOffset();
		int count = pageParam.getCount();
		String app_id = pageParam.getApp_id();
		return weChatService.getMaterialList(co_no,app_id,start,count);
	}
	
	@RequestMapping(value = "/addMaterialNews", method = RequestMethod.POST)
	@ResponseBody
	public BaseResult addMaterialNews(@RequestParam("co_no")Long co_no,@RequestParam("app_id")String app_id){
		return weChatService.addMaterialNews(co_no, app_id,null);
	}
	
	@RequestMapping(value = "/updateMaterialNews", method = RequestMethod.POST)
	@ResponseBody
	public BaseResult updateMaterialNews(@RequestParam("co_no")Long co_no,@RequestParam("app_id")String app_id){
		return weChatService.updateMaterialNews(co_no, app_id,null, 0, null);
	}
	
	@RequestMapping("thumb/{co_no}/{thumb_media_id}")
    public void getIcon(@PathVariable("co_no") String co_no, @PathVariable("thumb_media_id") String thumb_media_id, 
                        HttpServletRequest request,
                        HttpServletResponse response) throws Exception{

        if(StringUtils.isEmpty(thumb_media_id)) {
            thumb_media_id = "";
        }

        String fileName = request.getSession().getServletContext().getRealPath("/thumb")
                + "/" + co_no + "/"
                + thumb_media_id.trim() + ".jpg";

        File file = new File(fileName);

        //判断文件是否存在如果不存在就返回默认图标
        if(!(file.exists() && file.canRead())) {
        	logger.info("文件:{}不存在",file.getAbsolutePath());
            file = new File(request.getSession().getServletContext().getRealPath("/thumb")+
            			"/"+co_no+"/root.jpg");
        }
        response.setContentType("image/jpg");
        OutputStream outputStream = null;
        try{
        	outputStream = response.getOutputStream();
            FileUtils.copyFile(file, outputStream);        	
        }catch(Exception e){
        	e.printStackTrace();
        }finally{
        	if(outputStream!=null){
        		outputStream.flush();
        		outputStream.close();
        	}
        }
    }
	/**
	 * 发送模板消息
	 * @param co_no
	 * @param app_id
	 * @param template_id
	 * @param touser
	 * @param url
	 * @param content
	 * @return
	 */
	@RequestMapping(value="/sendTplMsg",method=RequestMethod.POST)
	@ResponseBody
	public BaseResult sendTemplateMessage(@RequestParam("co_no")Long co_no,
			@RequestParam("app_id")String app_id, @RequestParam("wx_tpl_no")String template_id,
			@RequestParam("open_id")String touser,@RequestParam("tpl_url")String url, 
			@RequestParam("content")String content){
		logger.debug("tpl_url:{}",url);
		List<TemplateMsgItemParam> templateMsgItemList = JSON.parseArray(content, TemplateMsgItemParam.class);
		LinkedHashMap<String, TemplateMessageItem> data = new LinkedHashMap<String, TemplateMessageItem>();
		if(CollectionUtils.isNotEmpty(templateMsgItemList)){
			for(TemplateMsgItemParam templateMsgItem:templateMsgItemList){
				data.put(templateMsgItem.getKey(), new TemplateMessageItem(templateMsgItem.getValue(),templateMsgItem.getColor()));
			}
		}
		return weChatService.sendMessageTemplate(co_no, app_id, template_id, touser, url, data);
	}
	
	/**
	 * 获取微信上传文件
	 * @param co_no
	 * @param app_id
	 * @param media_id
	 * @param request
	 * @param response
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	@RequestMapping(value="/getMedia",method=RequestMethod.POST)
	@ResponseBody
	public BaseResult getMedia(@RequestParam("co_no")Long co_no, @RequestParam(value="app_id",required=false)String app_id, @RequestParam("media_id")String media_id,
			HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException{
		return weChatService.getMedia(co_no,app_id,media_id);
	}
	
}
